home *** CD-ROM | disk | FTP | other *** search
- //-----------------------------------------------------------------------------
- //
- // Sample Name: ChatPeer Sample
- //
- // Copyright (c) 1999-2001 Microsoft Corporation. All rights reserved.
- //
- //-----------------------------------------------------------------------------
-
-
- Description
- ===========
- ChatPeer is similar in form to SimplePeer. Once a player hosts or connects
- to a session, the players can chat with either other by passing text
- strings.
-
- Path
- ====
- Source: DXSDK\Samples\Multimedia\DirectPlay\ChatPeer
-
- Executable: DXSDK\Samples\Multimedia\DirectPlay\Bin
-
- User's Guide
- ============
- Refer to User's Guide section of the SimplePeer sample.
-
- Programming Notes
- =================
- The ChatPeer sample is very similar in form to the SimplePeer sample. For
- detailed programming notes on the basics this sample, refer to Programming
- Notes section of the SimplePeer sample.
-
- The ChatPeer differs by letting clients send text strings to all players
- connected to the session.
-
- * The "Send" button is pressed. See SendChatMessage().
- 1. Retrieves the text string from the dialog.
- 2. Fills a app defined struct, GAMEMSG_CHAT. This struct has
- a message type ID as the first BYTE. This lets our app
- figure out what type of app message they received, however
- ChatPeer only uses one app defined message. See StagedPeer
- for a more complex example of this process.
- 3. Fills out a DPN_BUFFER_DESC struct using the GAMEMSG_CHAT buffer.
- 4. Calls IDirectPlay8Peer::SendTo() with the DPN_BUFFER_DESC. It passes
- DPNID_ALL_PLAYERS_GROUP so this message goes to everyone.
-
- * Handle DirectPlay system messages. See DirectPlayMessageHandler()
-
- The ChatPeer handles the typical messages as described in the
- SimplePeer programming notes, and in addition:
-
- - Upon DPN_MSGID_RECEIVE message:
- 1. It casts pReceiveMsg->pReceiveData into a generic app defined
- structure, GAMEMSG_GENERIC. This helps to figure out what structure
- is really contained in pReceiveMsg->pReceiveData. For this simple
- example, if the ID is GAME_MSGID_CHAT it casts the buffer to a
- GAMEMSG_CHAT*.
- 2. It then creates a new APP_QUEUED_DATA struct which contains a pointer
- to the GAMEMSG_CHAT buffer, and the a DirectPlay handle linked to the
- GAMEMSG_CHAT buffer.
- 3. We then post a user defined message, WM_APP_CHAT, to the dialog thread
- with the lParam equal to a pointer to the APP_QUEUED_DATA struct and
- the wParam equal to the DPNID of the player who sent us the buffer.
- We post a message since this lets us return from the DirectPlay message
- handler quickly. In a complex game if the handler threads take too
- long its possible that a backlog of network data may arise.
- 4. We return from DirectPlayMessageHandler() with the result code
- of DPNSUCCESS_PENDING. This error code tells DirectPlay that the buffer
- we got in the DPN_MSGID_RECEIVE message is still in use by our app.
- This allows us to not to have to copy the buffer, but instead pass a
- pointer of it off to a worker thread. This simple sample just uses
- the main dialog thread to process queued data. For a more complex
- example of this process see the DataRelay sample.
-
- * Upon receiving WM_APP_CHAT in the message loop
- This is posted to the message loop by one DirectPlay message handler threads
- whenever we receive a chat message. See above for more detail. Here's what
- happens:
-
- 1. Cast the wParam to a DPNID. This is the player that sent the message.
- 2. Calls IDirectPlay8Peer::GetPlayerContext(). This retrieves a user
- specified pointer (which we cast to a APP_PLAYER_INFO*) associated with
- this player. See the SimplePeer programming notes for more info on how
- this is setup. Also, note that since player can be deleted at any time,
- we need to use ref counting to make sure this player context struct isn't
- deleted while we are still using it.
- 3. Cast the lParam into a APP_QUEUED_DATA*. This tells us the buffer, and the DirectPlay
- handle associated with that buffer.
- 4. Process the buffer by adding it's text string to the dialog.
- 5. Release the APP_PLAYER_INFO* since we are done using it.
- 6. Now DirectPlay can free the receive buffer since we are done with it.
- So return the buffer to DirectPlay by calling IDirectPlay8Peer::ReturnBuffer,
- passing in the DirectPlay buffer handle.
- 7. Deletes the APP_QUEUED_DATA from the heap
-
-
-